/*
 * @(#)MaintWorkflowQueryRecordAction.java
 *
 * Copyright (c) 2004 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.web;

import java.sql.Connection;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractActionForm;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;
import com.dcivision.upload.core.MultipleFileUploadUtil;
import com.dcivision.workflow.action.AutoTaskStartSubWorkflow;
import com.dcivision.workflow.bean.MtmWfProgressWfProgress;
import com.dcivision.workflow.bean.MtmWorkflowProgressUserRecord;
import com.dcivision.workflow.bean.MtmWorkflowStepUserActor;
import com.dcivision.workflow.bean.MtmWorkflowTrackInterruptReq;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowProgressAttachment;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.bean.WorkflowStep;
import com.dcivision.workflow.core.WorkflowOperationManager;
import com.dcivision.workflow.core.WorkflowProgressManager;
import com.dcivision.workflow.core.WorkflowRetrievalManager;
import com.dcivision.workflow.dao.MtmWfProgressWfProgressDAObject;
import com.dcivision.workflow.dao.MtmWorkflowDynamicUserActorDAObject;
import com.dcivision.workflow.dao.MtmWorkflowProgressUserRecordDAObject;
import com.dcivision.workflow.dao.MtmWorkflowStepUserActorDAObject;
import com.dcivision.workflow.dao.MtmWorkflowStepWorkflowStepDAObject;
import com.dcivision.workflow.dao.MtmWorkflowTrackInterruptReqDAObject;
import com.dcivision.workflow.dao.WorkflowProgressDAObject;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;
import com.dcivision.workflow.dao.WorkflowStepDAObject;

/**
  MaintWorkflowRecordAction.java

  This class is for maint wprkflow record.

    @author          Angus Shiu
    @company         DCIVision Limited
    @creation date   29/07/2003
    @version         $Revision: 1.32.2.2 $
*/
public class MaintWorkflowInterruptStepAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.32.2.2 $";

  public static final String VAR_ACCESSIBLE_GROUP_LIST = "accessibleGroupList";
  public static final String NOT_INTERRUPT_TO_YOU="workflow.message.you_not_interrupt_mace";
  /** Creates a new instance of MaintWorkflowRecordAction */
  public MaintWorkflowInterruptStepAction() {
    super();
    this.setListName("listWorkflowStepList");
    this.setListFunctionName("getListByWorkflowRecordID");
  }

  /** getFunctionCode
   *
   * Abstract function which sub-class should implement to return the corresponding
   * function code.
   *
   * @return   The function code
   */
  public String getFunctionCode() {
    return(SystemFunctionConstant.WORKFLOW_TASK);
  }

  /** getMajorDAOClassName
   *
   * Abstract function which sub-class should implement to return the corresponding
   * major DAO class name used in this class.
   *
   * @return   The DAO class name
   */
  public String getMajorDAOClassName() {
    return("com.dcivision.workflow.dao.WorkflowStepDAObject");
  }

  public void clearUniqueFields(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    MaintWorkflowRecordForm workflowRecordForm = (MaintWorkflowRecordForm) form;
    workflowRecordForm.setID(null);
    workflowRecordForm.setWorkflowVersion(null);
    workflowRecordForm.setStatus(GlobalConstant.RECORD_PENDING);
    workflowRecordForm.setDescription(null);
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
    SessionContainer sessionContainer = (SessionContainer) request.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY);
    WorkflowRetrievalManager wfRetrievalManager = new WorkflowRetrievalManager(sessionContainer,this.getConnection(request));
    WorkflowProgressManager wfProgressManager = new WorkflowProgressManager(sessionContainer,this.getConnection(request));
    WorkflowStepDAObject workflowStepDAO = new WorkflowStepDAObject(sessionContainer,this.getConnection(request));
    WorkflowProgressDAObject workflowProgressDAO = new WorkflowProgressDAObject(sessionContainer,this.getConnection(request));
    WorkflowRecordDAObject workflowRecordDAO = new WorkflowRecordDAObject(sessionContainer,this.getConnection(request));
    MtmWorkflowProgressUserRecordDAObject progressUserRecordDAO = new MtmWorkflowProgressUserRecordDAObject(sessionContainer,this.getConnection(request));
    MtmWfProgressWfProgressDAObject mtmWfProgressWfProgressDAObject = new MtmWfProgressWfProgressDAObject(sessionContainer,this.getConnection(request));
    MtmWorkflowStepUserActorDAObject stepUserActorDAO = new MtmWorkflowStepUserActorDAObject(sessionContainer,this.getConnection(request));
    MaintWorkflowInterruptStepForm maintForm = (MaintWorkflowInterruptStepForm) form;
    boolean interruptionCompletedWf = SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.WORKFLOW_SUPPORT_INTERRUPTION_COMPLETED_WORKFLOW);

    String opMode = (maintForm!=null) ? maintForm.getOpMode() : request.getParameter("opMode");    //maintForm.getOpMode();
    String navMode = (maintForm!=null) ? maintForm.getNavMode() : request.getParameter("navMode"); //maintForm.getNavMode();

    //check whether the request come form applet
    String fromType = request.getParameter("fromType");
    log.debug( ((maintForm!=null) ? maintForm.getClass().getName() : "")+", OP Mode:"+opMode+", Nav Mode:"+navMode);
    if (Utility.isEmpty(maintForm.getWorkflowRecordID())) {
      maintForm.setWorkflowRecordID(request.getParameter("workflowRecordID"));
    }
    if (Utility.isEmpty(maintForm.getWorkflowProgressID())) {
      maintForm.setWorkflowProgressID(request.getParameter("ID"));
    }
//  check current user is interrupt allow
    // if current user is not have interrupt right
    //  maintForm.setInterruptAble(true);
    List userActorList = null;
    WorkflowProgress wfProgress = null;
    if (!Utility.isEmpty(maintForm.getWorkflowProgressID())) {
      wfProgress = (WorkflowProgress) workflowProgressDAO.getObjectByID(new Integer(maintForm.getWorkflowProgressID()));
    }
    
    // Set the function code for current action.
    // This function code is need for further operation.
    ActionForward forward = this.retrieveFunctionCode(request, response, mapping);  if (forward!=null) {return forward;}

    // Get the current step information
    // Current step has to be get in all navMode/opMode
    // in order to display the current step info upon error
    WorkflowStep currentStep;
    // Special handling for no workflow step specified
    if ( Utility.isEmpty(maintForm.getWorkflowStepID()) && !Utility.isEmpty(maintForm.getWorkflowTrackID()) ) {
      // get the list of open step of the track
      //List nonFinishedProgressList = workflowProgressDAO.getNonFinishedProgressListByTrackID ( Integer.valueOf(maintForm.getWorkflowTrackID()) );
      List interruptProgressList = new ArrayList();
      boolean isCompleteInterrupt = false;
      WorkflowProgress workflowProgress = null; 
      if(interruptionCompletedWf){
        interruptProgressList = workflowProgressDAO.getProgressListByTrackIDAndStatus(Integer.valueOf(maintForm.getWorkflowTrackID()),null);
        WorkflowProgress tmpworkflowProgress = (WorkflowProgress)interruptProgressList.get(0);
        if(!(GlobalConstant.TRUE).equals(tmpworkflowProgress.getCompleteFlag())){
          interruptProgressList = workflowProgressDAO.getNonFinishedProgressListByTrackID (Integer.valueOf(maintForm.getWorkflowTrackID()));	
        }else{
          isCompleteInterrupt = true;
        }
      }else{    
        interruptProgressList = workflowProgressDAO.getNonFinishedProgressListByTrackID (Integer.valueOf(maintForm.getWorkflowTrackID()));
      }
      try {
        // TODO: Need to handle for multiple open progress
    	 if(isCompleteInterrupt){
          workflowProgress = (WorkflowProgress)interruptProgressList.get(interruptProgressList.size()-1);
        }else{
          workflowProgress = (WorkflowProgress)interruptProgressList.get(0);
        }
        maintForm.setWorkflowStepID ( String.valueOf(workflowProgress.getWorkflowStepID()) );
        maintForm.setWorkflowProgressID ( String.valueOf(workflowProgress.getID()) );
        currentStep = (WorkflowStep)workflowStepDAO.getObjectByID(new Integer(maintForm.getWorkflowStepID()));
        if (Utility.isEmpty(wfProgress)) {
          wfProgress = workflowProgress;
        }
      } catch (Exception ex) {
        // Assume the track is not interruptable for any error occur
        addError(request, ErrorConstant.WORKFLOW_TRACK_CANNOT_BE_INTERRUPT);
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
      }
    }else{
      currentStep = (WorkflowStep)workflowStepDAO.getObjectByID(new Integer(maintForm.getWorkflowStepID()));
    }
    maintForm.setStepSeq(String.valueOf(currentStep.getStepSeq()));
    maintForm.setStepName(currentStep.getStepName());
    // Finished getting current step information
    /*if (!Utility.isEmpty(wfProgress) && !Utility.isEmpty(maintForm.getWorkflowRecordID())) {
      userActorList = wfProgressManager.getInterruptActorIDListByProgressIDAndRecordID(wfProgress, new Integer(maintForm.getWorkflowRecordID()));
    }
    for (int k = 0; !Utility.isEmpty(userActorList) && k < userActorList.size(); k++) {
      Integer userActorID = (Integer)userActorList.get(k);
      if(this.getSessionContainer(request).getUserRecordID().equals(userActorID)) {
        maintForm.setInterruptAble(true);
        break;
      }
    }*/
    maintForm.setInterruptAble(wfProgressManager.CheckInterruptAble(wfProgress, new Integer(maintForm.getWorkflowRecordID())));//TC.ADD FOR BUG-1745
    if ((!Utility.isEmpty(opMode) && !Utility.isEmpty(navMode) && GlobalConstant.NAV_MODE_LIST.equals(opMode) &&
            GlobalConstant.NAV_MODE_LIST.equals(navMode)) || GlobalConstant.NAV_MODE_LIST.equals(fromType))
    {
      List listWorkflowStepList = new ArrayList();
      if (maintForm.isInterruptAble()) {// check interruptAble is not true ;
      //if request come from applet,sendRedirect to applet
        if (GlobalConstant.NAV_MODE_LIST.equals(fromType)) {
          maintForm.setWorkflowTrackID(request.getParameter("workflowTrackID"));
          maintForm.setWorkflowProgressID(request.getParameter("ID"));
          maintForm.setWorkflowStepID(request.getParameter("workflowStepID"));
        }

//      if (Utility.isEmpty(maintForm.getInterruptType())) {
//        listWorkflowStepList = workflowStepDAO.getListByWorkflowRecordID(new Integer(maintForm.getWorkflowRecordID()));
//      }

        if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(maintForm.getInterruptType())) {
          List listWorkflowStepListStr = new ArrayList();
        boolean includeAutoTask = SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.WORKFLOW_INTERRUPTION_INCLUDE_AUTOTASK);
          listWorkflowStepListStr = wfRetrievalManager.getSuperStepList(new Integer(maintForm.getWorkflowStepID()), listWorkflowStepListStr, includeAutoTask);
          for(int h = 0; !Utility.isEmpty(listWorkflowStepListStr) && h < listWorkflowStepListStr.size(); h++){
            WorkflowStep wfStep = (WorkflowStep)listWorkflowStepListStr.get(h);
            if(!WorkflowStep.START_STEP_SEQ_NO.equals(wfStep.getStepSeq())) {
              listWorkflowStepList.add(wfStep);
            }
          }
           log.debug("the workflowSteplist is ................." + listWorkflowStepList.size());
          Integer targetStepID = null;
          if (Utility.isEmpty(maintForm.getTargetStepID()) && !Utility.isEmpty(listWorkflowStepList)) {
            targetStepID = ((WorkflowStep)listWorkflowStepList.get(0)).getID();
          } else if (!Utility.isEmpty(maintForm.getTargetStepID())) {
            targetStepID = TextUtility.parseIntegerObj(maintForm.getTargetStepID());
          }
          maintForm.setPenddingBranches(this.getAllPenddingBranches(TextUtility.parseIntegerObj(maintForm.getWorkflowTrackID()), targetStepID, request));
        }
        if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_SKIP.equals(maintForm.getInterruptType())) {
          List listWorkflowStepListStr = wfRetrievalManager.getChildStepList(new Integer(maintForm.getWorkflowStepID()), listWorkflowStepList);
          for(int h = 0; !Utility.isEmpty(listWorkflowStepListStr) && h < listWorkflowStepListStr.size(); h++){
            WorkflowStep wfStep = (WorkflowStep)listWorkflowStepListStr.get(h);
            if(!WorkflowStep.END_STEP_SEQ_NO.equals(wfStep.getStepSeq())) {
              listWorkflowStepList.add(wfStep);
            }
          }
          log.debug("the workflowSteplist is ................." + listWorkflowStepList.size());
        }
        if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_REVOKE.equals(maintForm.getInterruptType())) {
//        WorkflowStep workflowStep = (WorkflowStep)workflowStepDAO.getObjectByID(new Integer(maintForm.getWorkflowStepID()));
          if (!Utility.isEmpty(currentStep)) {
            listWorkflowStepList.add(currentStep);
            log.debug("the workflowSteplist is ................." + listWorkflowStepList.size());
          }
        }
      } else {
        addError(request, NOT_INTERRUPT_TO_YOU);
      }
      request.setAttribute("listWorkflowStepList",listWorkflowStepList);
      return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
    }
    if (!Utility.isEmpty(opMode) && GlobalConstant.OP_MODE_INSERT.equals(opMode)) {
      
      WorkflowProgress workflowProgress = (WorkflowProgress) workflowProgressDAO.getObjectByID(new Integer(maintForm.getWorkflowProgressID()));
      WorkflowRecord workflowRecord = (WorkflowRecord)workflowRecordDAO.getObjectByID(new Integer(maintForm.getWorkflowRecordID()));
      if (!Utility.isEmpty(workflowProgress) && WorkflowRecord.INTERRUPT_WORKFLOW_ALLOW_YES.equals(workflowRecord.getAllowInterrupt())) {
        if (!Utility.isEmpty(workflowRecord.getInterruptWorkflowRecordID())) {
          if ((MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(maintForm.getInterruptType()) && GlobalConstant.TRUE.equals(maintForm.getIsRollbackAllBranches())) || MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_STOP.equals(maintForm.getInterruptType())) {
            // Find between start interrupt step and object Step is all progressing step(pendding/in progress progress)
            // Locked all found progress
            List progressList = new ArrayList();
            if(MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(maintForm.getInterruptType())) {
              progressList = wfRetrievalManager.getInterruptedProgressList(workflowProgress.getTrackID(), new Integer(maintForm.getTargetStepID()));
            } else {
              progressList = wfRetrievalManager.getInterruptedProgressList(workflowProgress.getTrackID(), null);
            }
            for (int i = 0; i < progressList.size(); i++) {
              WorkflowProgress currentProgress = (WorkflowProgress)progressList.get(i);
              if (workflowProgress.getID().equals(currentProgress.getID())) {
                workflowProgress.setStatus(WorkflowProgress.STATUS_LOCK);
                workflowProgress = (WorkflowProgress) workflowProgressDAO.updateObject(workflowProgress);
              } else {
                currentProgress.setStatus(WorkflowProgress.STATUS_LOCK);
                currentProgress =(WorkflowProgress) workflowProgressDAO.updateObject(currentProgress);
              }
//            insert status is rollback record for User_record
              MtmWorkflowProgressUserRecord progressUserRecord = new MtmWorkflowProgressUserRecord();

              progressUserRecord.setWorkflowProgressID(currentProgress.getID());
              progressUserRecord.setUserRecordID(sessionContainer.getUserRecordID());
              progressUserRecord.setWorkflowAction(WorkflowProgress.STATUS_LOCK);
              progressUserRecord = (MtmWorkflowProgressUserRecord) progressUserRecordDAO.insertObject(progressUserRecord);
            }
          } else {
            workflowProgress.setStatus(WorkflowProgress.STATUS_LOCK);
            workflowProgress =(WorkflowProgress) workflowProgressDAO.updateObject(workflowProgress);
          }
          MtmWorkflowTrackInterruptReq interruptReq = this.insertRecord(mapping, maintForm, request, response);
          this.createScheduleStartSubWorkflow(workflowProgress, interruptReq);
        } else {
          if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(maintForm.getInterruptType())) {
            if (GlobalConstant.TRUE.equals(maintForm.getIsRollbackAllBranches())) {
              List progressList = wfRetrievalManager.getInterruptedProgressList(workflowProgress.getTrackID(), new Integer(maintForm.getTargetStepID()));
              for (int i = 0; i < progressList.size(); i++) {
                WorkflowProgress currentProgress = (WorkflowProgress)progressList.get(i);
                currentProgress.setStatus(WorkflowProgress.STATUS_ROLLBACK);
                currentProgress =(WorkflowProgress) workflowProgressDAO.updateObject(currentProgress);
                // insert status is rollback record for User_record
                MtmWorkflowProgressUserRecord progressUserRecord = new MtmWorkflowProgressUserRecord();

                progressUserRecord.setWorkflowProgressID(currentProgress.getID());
                progressUserRecord.setUserRecordID(sessionContainer.getUserRecordID());
                progressUserRecord.setWorkflowAction(currentProgress.getStatus());
                progressUserRecord.setReason(maintForm.getReason());
                progressUserRecord = (MtmWorkflowProgressUserRecord) progressUserRecordDAO.insertObject(progressUserRecord);
                //falcon_add_start, prepare the list of workflow attachment
                SessionContainer sessionCon = this.getSessionContainer(request);
                Connection dbConn = this.getConnection(request);
                if ( !Utility.isEmpty(maintForm.getFileNames()) ) {
                  MultipleFileUploadUtil uploadUtil = new MultipleFileUploadUtil(sessionCon);
                  List attachmentList = uploadUtil.getWorkflowAttachmentList(maintForm.getFileNames(), WorkflowProgressAttachment.ATTACHED_SINGLE_FILE);
                  maintForm.setAttachmentList(attachmentList);
                }
                if ( !Utility.isEmpty(maintForm.getDmsFileNames()) ) {
           	     List attachmentList = new ArrayList();
           	     if (maintForm.getAttachmentList()!=null) {
           	       attachmentList = maintForm.getAttachmentList();
           	     }
           	     if(!Utility.isEmpty(this.getDmsDocumentAttachment(maintForm))){
           	        attachmentList.addAll(this.getDmsDocumentAttachment(maintForm));
           	     }
           	     maintForm.setAttachmentList(attachmentList);
           	   }
                WorkflowOperationManager wfOperationManager = new WorkflowOperationManager(sessionCon, dbConn);
                wfOperationManager.createWorkflowProgressAttachments(maintForm.getAttachmentList(), progressUserRecord.getID());
               //falcon_add_end
                // Update current progress is Calendar record;
                wfProgressManager.editCalendarByProgressID(currentProgress.getID(), null);
              }
            } else {
              workflowProgress.setStatus(WorkflowProgress.STATUS_ROLLBACK);
              workflowProgress =(WorkflowProgress) workflowProgressDAO.updateObject(workflowProgress);
//            Update current progress is Calendar record;
              wfProgressManager.editCalendarByProgressID(workflowProgress.getID(), null);
            }
          } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_REVOKE.equals(maintForm.getInterruptType())) {
            workflowProgress.setStatus(WorkflowProgress.STATUS_REVOKE);
            workflowProgress =(WorkflowProgress) workflowProgressDAO.updateObject(workflowProgress);
            //Update current progress is Calendar record;
            wfProgressManager.editCalendarByProgressID(workflowProgress.getID(), null);
          } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_SKIP.equals(maintForm.getInterruptType())) {
            workflowProgress.setStatus(WorkflowProgress.STATUS_SKIP);
            workflowProgress =(WorkflowProgress) workflowProgressDAO.updateObject(workflowProgress);
            // Update current progress is Calendar record;
            wfProgressManager.editCalendarByProgressID(workflowProgress.getID(), null);
          } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_STOP.equals(maintForm.getInterruptType())) {
            List progressList = wfRetrievalManager.getInterruptedProgressList(workflowProgress.getTrackID(), null);
            for (int i = 0; i < progressList.size(); i++) {
              WorkflowProgress currentProgress = (WorkflowProgress)progressList.get(i);
              currentProgress.setStatus(WorkflowProgress.STATUS_CANCEL);
              currentProgress =(WorkflowProgress) workflowProgressDAO.updateObject(currentProgress);
              // insert status is rollback record for User_record
              MtmWorkflowProgressUserRecord progressUserRecord = new MtmWorkflowProgressUserRecord();

              progressUserRecord.setWorkflowProgressID(currentProgress.getID());
              progressUserRecord.setUserRecordID(sessionContainer.getUserRecordID());
              progressUserRecord.setWorkflowAction(currentProgress.getStatus());
              progressUserRecord.setReason(maintForm.getReason());
              progressUserRecord = (MtmWorkflowProgressUserRecord) progressUserRecordDAO.insertObject(progressUserRecord);
              //falcon_add_start, prepare the list of workflow attachment
              SessionContainer sessionCon = this.getSessionContainer(request);
              Connection dbConn = this.getConnection(request);
              if ( !Utility.isEmpty(maintForm.getFileNames()) ) {
                MultipleFileUploadUtil uploadUtil = new MultipleFileUploadUtil(sessionCon);
                List attachmentList = uploadUtil.getWorkflowAttachmentList(maintForm.getFileNames(), WorkflowProgressAttachment.ATTACHED_SINGLE_FILE);
                maintForm.setAttachmentList(attachmentList);
              }
              if ( !Utility.isEmpty(maintForm.getDmsFileNames()) ) {
         	     List attachmentList = new ArrayList();
         	     if (maintForm.getAttachmentList()!=null) {
         	       attachmentList = maintForm.getAttachmentList();
         	     }
         	     if(!Utility.isEmpty(this.getDmsDocumentAttachment(maintForm))){
         	        attachmentList.addAll(this.getDmsDocumentAttachment(maintForm));
         	     }
         	     maintForm.setAttachmentList(attachmentList);
         	   }
              WorkflowOperationManager wfOperationManager = new WorkflowOperationManager(sessionCon, dbConn);
              wfOperationManager.createWorkflowProgressAttachments(maintForm.getAttachmentList(), progressUserRecord.getID());
             //falcon_add_end
              // Update current progress is Calendar record;
              wfProgressManager.editCalendarByProgressID(workflowProgress.getID(), null);
            }
          }
         
          this.insertRecord(mapping, maintForm, request, response);
          if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(maintForm.getInterruptType()) || MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_REVOKE.equals(maintForm.getInterruptType())) {
            List newProgressList = workflowProgressDAO.getListByStepIDAndTrackID(new Integer(maintForm.getTargetStepID()), new Integer(maintForm.getWorkflowTrackID()));
            WorkflowProgress newProgress = new WorkflowProgress();
            if (!Utility.isEmpty(newProgressList)) {
              newProgress = (WorkflowProgress)newProgressList.get(0);
            }

            newProgress.setStatus(WorkflowProgress.STATUS_PENDING);
            List progressList = workflowProgressDAO.getListByTrackID(workflowProgress.getTrackID());
            log.debug("progressList size: "+progressList.size());
            int seqNoCount = progressList.size() + 1;
            newProgress.setSeqNo(new Integer(seqNoCount));
            WorkflowStep workflowStep = (WorkflowStep)workflowStepDAO.getObjectByID(newProgress.getWorkflowStepID());
            newProgress.setProgressPriority(workflowStep.getPriority());
            newProgress.setID(null);
            newProgress = (WorkflowProgress)workflowProgressDAO.insertObject(newProgress);
//          create notification job for this step
            boolean actorTypeIsAssgin = false;
            List allUserActorList = stepUserActorDAO.getListByWorkflowStepID(newProgress.getWorkflowStepID());
            if (!Utility.isEmpty(allUserActorList)) {
              for(int j = 0; j < allUserActorList.size(); j++) {
                MtmWorkflowStepUserActor stepUserActor = (MtmWorkflowStepUserActor)allUserActorList.get(j);
                if (MtmWorkflowStepUserActor.ACTOR_TYPE_RUNTIME_ASSIGN.equals(stepUserActor.getActorType())) {
                  actorTypeIsAssgin = true;
                }
              }
            }
            if (!actorTypeIsAssgin) {
              wfProgressManager.createNotificationWhenTaskArrived(newProgress.getID());
            }
          //   set dynamic assign priority.
            wfProgressManager.createScheduleForProgressPriority(newProgress.getID(), sessionContainer,this.getConnection(request));
            // falcon_add_S_5846
            MtmWfProgressWfProgress mtmWfProgressWfProgress = new MtmWfProgressWfProgress();
            mtmWfProgressWfProgress.setChildProgressID(newProgress.getID());
            mtmWfProgressWfProgress.setChildCreateType(newProgress.getChildCreateType());
            mtmWfProgressWfProgress.setParentProgressID(workflowProgress.getID());
            mtmWfProgressWfProgressDAObject.insertObject(mtmWfProgressWfProgress);
            // falcon_add_E  
            // if new progress is assign user owner is assign ,get old user action taker to new
            this.insertUserRecordForAssignUser(newProgress, request);
          } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_SKIP.equals(maintForm.getInterruptType())) {
            WorkflowStep newStep = (WorkflowStep)workflowStepDAO.getObjectByID(new Integer(maintForm.getTargetStepID()));
            wfProgressManager.createNextWorkflowProgressesForSkipWorkflow(workflowProgress, newStep);
          }
        }
          
          // Record progress-user info into DB if we haven't done before.
          if (!(MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(maintForm.getInterruptType()) && GlobalConstant.TRUE.equals(maintForm.getIsRollbackAllBranches())) && !MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_STOP.equals(maintForm.getInterruptType())) {
            MtmWorkflowProgressUserRecord progressUserRecord = new MtmWorkflowProgressUserRecord();

            progressUserRecord.setWorkflowProgressID(workflowProgress.getID());
            progressUserRecord.setUserRecordID(sessionContainer.getUserRecordID());
            progressUserRecord.setWorkflowAction(workflowProgress.getStatus());
            progressUserRecord.setReason(maintForm.getReason());
            progressUserRecord = (MtmWorkflowProgressUserRecord) progressUserRecordDAO.insertObject(progressUserRecord);
          }
      }
      this.commit(request);
      request.setAttribute(GlobalConstant.ACTION_MODE, GlobalConstant.NAV_MODE_VIEW);
      maintForm.setNavMode(GlobalConstant.NAV_MODE_VIEW);
      request.setAttribute("maintWorkflowInterruptStepForm", maintForm);
      return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);
    } else {
      return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);
    }
  }

  /**
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public MtmWorkflowTrackInterruptReq insertRecord(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    MtmWorkflowTrackInterruptReqDAObject  workflowTrackInterruptReqDAO = new MtmWorkflowTrackInterruptReqDAObject(this.getSessionContainer(request), this.getConnection(request));
    MtmWorkflowTrackInterruptReq workflowTrackInterruptReq = new MtmWorkflowTrackInterruptReq();
    MaintWorkflowInterruptStepForm maintForm = (MaintWorkflowInterruptStepForm)form;
    try {
      workflowTrackInterruptReq.setWorkflowTrackID(new Integer(maintForm.getWorkflowTrackID()));
      if (!Utility.isEmpty(maintForm.getTargetStepID())) {
        workflowTrackInterruptReq.setTargetStepID(new Integer(maintForm.getTargetStepID()));
      } else {
        workflowTrackInterruptReq.setTargetStepID(new Integer(0));
      }
      workflowTrackInterruptReq.setInterruptType(new Integer(maintForm.getInterruptType()));
      workflowTrackInterruptReq.setInterruptStatus(WorkflowProgress.STATUS_PENDING);
      workflowTrackInterruptReq = (MtmWorkflowTrackInterruptReq)workflowTrackInterruptReqDAO.insertObject(workflowTrackInterruptReq);
    } catch (ApplicationException ex) {
      log.error(ex, ex);
      this.rollback(request);
    }
    return workflowTrackInterruptReq;
  }

  /**
   *
   * @param parentProgress
   * @param childProgress
   * @param request
   * @throws ApplicationException
   */
  public void insertRecordForProgressAndProgress(WorkflowProgress parentProgress, WorkflowProgress childProgress, HttpServletRequest request)throws ApplicationException {
    MtmWfProgressWfProgressDAObject mtmWfProgressWfProgressDAO = new MtmWfProgressWfProgressDAObject(this.getSessionContainer(request), this.getConnection(request));
    MtmWorkflowStepWorkflowStepDAObject mtmWorkflowStepWorkflowStepDAO = new MtmWorkflowStepWorkflowStepDAObject(this.getSessionContainer(request), this.getConnection(request));
    WorkflowProgressDAObject workflowProgressDAO = new WorkflowProgressDAObject(this.getSessionContainer(request), this.getConnection(request));
    MtmWfProgressWfProgress mtmWfProgressWfProgress = new MtmWfProgressWfProgress();
    try {
      mtmWfProgressWfProgress.setParentProgressID(parentProgress.getID());
      mtmWfProgressWfProgress.setChildProgressID(childProgress.getID());
      mtmWfProgressWfProgress.setChildCreateType(parentProgress.getStatus());
      mtmWfProgressWfProgress = (MtmWfProgressWfProgress)mtmWfProgressWfProgressDAO.insertObject(mtmWfProgressWfProgress);
    } catch (ApplicationException ex){
      log.error(ex, ex);
    }
  }

 public void insertUserRecordForAssignUser(WorkflowProgress workflowProgress, HttpServletRequest request)throws ApplicationException {
   MtmWorkflowStepUserActorDAObject mtmWorkflowStepUserActorDAObject = new MtmWorkflowStepUserActorDAObject(this.getSessionContainer(request), this.getConnection(request));
   MtmWorkflowProgressUserRecordDAObject progressUserRecordDAO = new MtmWorkflowProgressUserRecordDAObject(this.getSessionContainer(request), this.getConnection(request));
   MtmWorkflowDynamicUserActorDAObject dynamicUserActorDAO = new MtmWorkflowDynamicUserActorDAObject(this.getSessionContainer(request), this.getConnection(request));
   WorkflowProgressDAObject workflowProgessDAO = new WorkflowProgressDAObject(this.getSessionContainer(request), this.getConnection(request));
   try {
     MtmWorkflowStepUserActor mtmWorkflowStepUserActor = mtmWorkflowStepUserActorDAObject.getWorkflowStepUserActorByWorkflowStepID(workflowProgress.getWorkflowStepID());
     if (!Utility.isEmpty(mtmWorkflowStepUserActor)) {
       WorkflowProgress currentProgress = null;
       List workflowProgressList = workflowProgessDAO.getListByStepIDAndTrackID(workflowProgress.getWorkflowStepID(), workflowProgress.getTrackID());
       if (!Utility.isEmpty(workflowProgressList)) {
         currentProgress = (WorkflowProgress)workflowProgressList.get(0);
         List mtmUserRecordList = progressUserRecordDAO.getListByWorkflowProgressID(currentProgress.getID());
         for (int h = 0; !Utility.isEmpty(mtmUserRecordList) && h < mtmUserRecordList.size(); h++) {
           MtmWorkflowProgressUserRecord  mtmUserRecord = (MtmWorkflowProgressUserRecord)mtmUserRecordList.get(h);
           mtmUserRecord.setID(null);
           mtmUserRecord.setWorkflowProgressID(workflowProgress.getID());
           mtmUserRecord.setWorkflowAction(WorkflowProgress.STATUS_PENDING);
           mtmUserRecord = (MtmWorkflowProgressUserRecord)progressUserRecordDAO.insertObject(mtmUserRecord);
         }
         // copy record dynamicUserActor table
         dynamicUserActorDAO.copyRecordByWorkflowProgressID(currentProgress.getID(), workflowProgress.getID());
       }
     }
   }catch (ApplicationException ex) {
     log.error(ex, ex);
   }
 }

 private void createScheduleStartSubWorkflow(
         WorkflowProgress currentProgress,
         MtmWorkflowTrackInterruptReq interruptReq
         ) throws ApplicationException {

     Timestamp scheduleDate = null;
     org.quartz.SimpleTrigger trigger = null;


     try {
     log.info("scheduledJobVec.size(): " );
     org.quartz.Scheduler sched = com.dcivision.framework.SchedulerFactory.getScheduler(); ;

     //logger.info("******** Adding schedule for Alert on = "+updateAlert.getObjectType()+ " object ID = " + updateAlert.getObjectID());

     org.quartz.JobDataMap dataMap = new org.quartz.JobDataMap();
     dataMap.put("currentProgress", currentProgress);
     dataMap.put("trackInterruptReq", interruptReq);

     // get interruptType ;
     String interruptStr = null;
     if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_ROLLBACK.equals(interruptReq.getInterruptType().toString())) {
       interruptStr = WorkflowProgress.STATUS_ROLLBACK;
     } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_REVOKE.equals(interruptReq.getInterruptType().toString())) {
       interruptStr = WorkflowProgress.STATUS_REVOKE;
     } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_SKIP.equals(interruptReq.getInterruptType().toString())) {
       interruptStr = WorkflowProgress.STATUS_SKIP;
     } else if (MtmWorkflowTrackInterruptReq.INTERRUPT_TYPE_STOP.equals(interruptReq.getInterruptType().toString())) {
       interruptStr = WorkflowProgress.STATUS_CANCEL;
     }

     org.quartz.JobDetail job = new org.quartz.JobDetail(
             GlobalConstant.JOB_PREFIX_WORKFLOW_INTERRUPT + interruptStr + "_" + currentProgress.getTrackID() + "_" + currentProgress.getID(),
             GlobalConstant.JOB_PREFIX_WORKFLOW_INTERRUPT  + "GROUP",
         AutoTaskStartSubWorkflow.class);
     job.setJobDataMap(dataMap);
     scheduleDate = new Timestamp(System.currentTimeMillis() + 10000);


     log.info("******** Schedule date: " + scheduleDate.toString());
     trigger = new org.quartz.SimpleTrigger(GlobalConstant.JOB_PREFIX_WORKFLOW_INTERRUPT + interruptStr + "_" + currentProgress.getTrackID() + "_" + currentProgress.getID(),
             GlobalConstant.JOB_PREFIX_WORKFLOW_INTERRUPT  + "GROUP",
                scheduleDate, null,0,0);

     trigger.setMisfireInstruction(org.quartz.SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
     log.info("******** Trigger created");
     log.info(job.getFullName() + " will run at: " + trigger.getNextFireTime() + " & repeat: " + trigger.getRepeatCount() + "/" + trigger.getRepeatInterval());

     java.util.Date ft = sched.scheduleJob(job, trigger);
     log.info("******** Trigger created");
     sched = null;
     } catch (Exception e) {
       log.error("Error in Scheduler.", e);
       throw new ApplicationException(ErrorConstant.SYS_SCHEDULER_ERROR);
     }
 }
 
 private String getAllPenddingBranches(Integer trackID, Integer targetStepID, HttpServletRequest request) throws ApplicationException {
   List penddingBranchesList = new ArrayList();
   String penddingBranches = new String();
   WorkflowRetrievalManager wfRetrievalManager = new WorkflowRetrievalManager(this.getSessionContainer(request),this.getConnection(request));
   WorkflowStepDAObject stepDAO = new WorkflowStepDAObject(this.getSessionContainer(request),this.getConnection(request));
   penddingBranchesList = wfRetrievalManager.getInterruptedProgressList(trackID, targetStepID);
   log.debug("the penddingBranchesList size::" + penddingBranchesList.size());
   if (penddingBranchesList.size() > 1){
     for (int i = 0; i < penddingBranchesList.size(); i++) {
       WorkflowProgress workflowProgress = (WorkflowProgress)penddingBranchesList.get(i);
       WorkflowStep currentStep = (WorkflowStep)stepDAO.getObjectByID(workflowProgress.getWorkflowStepID());
       penddingBranches += "[" + currentStep.getStepSeq().toString() + "." + currentStep.getStepName() + "]";
     }
   }
   log.debug("The penddingBranches is :::" + penddingBranches);
   return penddingBranches;
 }
 /**
  * falcon_add
  * get Dms Document Attachment list
  * @param form
  * @return
  */
 private List getDmsDocumentAttachment(AbstractSearchForm form){
	MaintWorkflowInterruptStepForm maintForm = (MaintWorkflowInterruptStepForm) form;
    String dmsFileNames = "";
    if(!Utility.isEmpty(maintForm.getDmsFileNames())){
        dmsFileNames = maintForm.getDmsFileNames();
    }
    List resultList = new ArrayList();
    WorkflowProgressAttachment attachment = null;
    String[] fileNameArray = TextUtility.splitString(dmsFileNames,GlobalConstant.FILENAME_SEPARATOR);

     for (int i=0; i<fileNameArray.length; i++) {
       String[] arrName = TextUtility.splitString(fileNameArray[i],":");

       String externalID = arrName[0];
       String fileName = arrName[1];
       String contentSize = arrName[2];

       externalID = externalID.substring(1,externalID.length()-1);
       fileName = fileName.substring(1,fileName.length()-1);
       contentSize = contentSize.substring(1,contentSize.length()-1);

       attachment = new WorkflowProgressAttachment();
       attachment.setAttachmentName(fileName);
       attachment.setExternalID(externalID);
       attachment.setFlowType(WorkflowProgressAttachment.ATTACHED_SINGLE_FILE);
       attachment.setContentSize(new Integer(contentSize));
       attachment.setAttachmentType(WorkflowProgressAttachment.ATTACHED_DMS_VERSION_SYSTEM_ID);
       resultList.add(attachment);
     }
     return resultList;
 }
}
